﻿
#include "MvCameraControl.h"

#include "camera_hk.h"
#include <string>


void __stdcall ImageCallBackEx(unsigned char* pData, MV_FRAME_OUT_INFO_EX* pFrameInfo, void* pUser)
{
    HkCamera* p = (HkCamera*)pUser;
        if (NULL == pFrameInfo || NULL == pData)
        {
            printf("NULL info or data.\n");
            return;
        }
        cv::Mat image;

        if (MvGvspPixelType::PixelType_Gvsp_Mono8 == pFrameInfo->enPixelType)
        {
            image = cv::Mat(pFrameInfo->nHeight, pFrameInfo->nWidth, CV_8UC1, pData);
            p->m_CallBack(image, p->m_Context);
        }
        if (MvGvspPixelType::PixelType_Gvsp_BayerRG8 == pFrameInfo->enPixelType)
        {
            image = cv::Mat(pFrameInfo->nHeight, pFrameInfo->nWidth, CV_8UC1, pData);
            cv::cvtColor(image, image, cv::COLOR_BayerBG2BGR);
            p->m_CallBack(image, p->m_Context);
        }
        if (MvGvspPixelType::PixelType_Gvsp_BayerBG8 == pFrameInfo->enPixelType)
        {
            // Mat像素排列格式为BGR，需要转换

            image = cv::Mat(pFrameInfo->nHeight, pFrameInfo->nWidth, CV_8UC1, pData);
            cv::cvtColor(image, image, cv::COLOR_BayerBGGR2BGR);
            p->m_CallBack(image, p->m_Context);
        }
        if (MvGvspPixelType::PixelType_Gvsp_BayerGB8 == pFrameInfo->enPixelType)
        {
            // Mat像素排列格式为BGR，需要转换

            image = cv::Mat(pFrameInfo->nHeight, pFrameInfo->nWidth, CV_8UC1, pData);
            cv::cvtColor(image, image, cv::COLOR_BayerGBRG2BGR);
            p->m_CallBack(image, p->m_Context);
        }
        if (MvGvspPixelType::PixelType_Gvsp_RGB8_Packed == pFrameInfo->enPixelType)
        {
            // Mat像素排列格式为BGR，需要转换

            image = cv::Mat(pFrameInfo->nHeight, pFrameInfo->nWidth, CV_8UC3, pData);
            cv::cvtColor(image, image, cv::COLOR_RGB2BGR);
            p->m_CallBack(image, p->m_Context);
        }
}

void __stdcall ExceptionCallBack(unsigned int nMsgType, void* pUser)
{
//    if (nMsgType == MV_EXCEPTION_DEV_DISCONNECT)
//    {
//        logger->info("MV_EXCEPTION_DEV_DISCONNECT");
//    }
//    else
//    {
	
    logger->info("Unknown exception 0x" + std::to_string(nMsgType));
//    }
	cv::Mat image(600, 800, CV_8UC3, cv::Scalar(255, 255, 255));
	
	// 设置文本属性
	int fontFace = cv::FONT_HERSHEY_SIMPLEX; // 字体类型
	double fontScale = 3; // 字体大小
	cv::Scalar textColor(0, 0, 255); // 文本颜色（黑色）
	int thickness = 2; // 文本线条粗细
	// 在图像上绘制文本
	cv::putText(image, "Camera NG", Point(100,100), fontFace, fontScale, textColor, thickness);

	cv::imshow("相机失去连接", image);
	cv::waitKey(0);


}

bool HkCamera::camera_init(char* name, CameraCallback pfunction, void* pcontext)
{
//	m_name = name;
    // ch:枚举设备 | Enum device
    MV_CC_DEVICE_INFO_LIST stDeviceList;
    memset(&stDeviceList, 0, sizeof(MV_CC_DEVICE_INFO_LIST));
    int nRet = MV_CC_EnumDevices(MV_GIGE_DEVICE | MV_USB_DEVICE, &stDeviceList);
    if (MV_OK != nRet)
    {
        return false;
    }

    for (unsigned int i = 0; i < stDeviceList.nDeviceNum; i++)
    {
        MV_CC_DEVICE_INFO* pDeviceInfo = stDeviceList.pDeviceInfo[i];

        if ((strcmp((char*)(pDeviceInfo->SpecialInfo.stGigEInfo.chSerialNumber), name) == 0) || (strcmp((char*)(pDeviceInfo->SpecialInfo.stUsb3VInfo.chSerialNumber), name)==0))
        {
            // ch:选择设备并创建句柄 | Select device and create handle
            nRet = MV_CC_CreateHandle(&m_camera_handle, stDeviceList.pDeviceInfo[i]);
            if (MV_OK != nRet)
            {
                    //QMessageBox::warning(nullptr, "错误", "Create Handle fail");
                return false;
            }

            // ch:打开设备 | Open device
            nRet = MV_CC_OpenDevice(m_camera_handle);
            if (MV_OK != nRet)
            {
                //QMessageBox::warning(nullptr, "错误", "Open Device fail");
                return false;
            }
			// Register disconnected exception callBack
			nRet = MV_CC_RegisterExceptionCallBack(m_camera_handle, ExceptionCallBack, this);
			if (MV_OK != nRet)
			{
				break;
			}
            // ch:注册抓图回调 | en:Register image callback
            nRet = MV_CC_RegisterImageCallBackEx(m_camera_handle, ImageCallBackEx, this);
            if (MV_OK != nRet)
            {
                //QMessageBox::warning(nullptr, "错误", "Register Image CallBack fail");
                return false;
            }
            // ch:设置缓存节点个数 | en:Set number of image node
                 nRet = MV_CC_SetImageNodeNum(m_camera_handle, 100);
                 if (MV_OK != nRet)
                 {
                     return false;
                 }


            // ch:开始取流 | en:Start grab image
            nRet = MV_CC_StartGrabbing(m_camera_handle);
            if (MV_OK != nRet)
            {
                //QMessageBox::warning(nullptr, "错误", "Start Grabbing fail!");
                return false;
            }
            m_CallBack = pfunction;
            m_Context = pcontext;
            return true;
        }
    }
    if (m_camera_handle == nullptr)
    {
        return false;
    }
    return false;
}

bool HkCamera::camera_end()
{
    if (m_camera_handle == nullptr)
    {
        return false;
    }
//    // ch:停止取流 | en:Stop grab image
//    int nRet = MV_CC_StopGrabbing(m_camera_handle);
//    if (MV_OK != nRet)
//    {
//        printf("Stop Grabbing fail! nRet [0x%x]\n", nRet);
//        return false;
//    }

    // ch:注销抓图回调 | en:Unregister image callback
    int nRet = MV_CC_RegisterImageCallBackEx(m_camera_handle, NULL, NULL);
    if (MV_OK != nRet)
    {
//        printf("Unregister Image CallBack fail! nRet [0x%x]\n", nRet);
        return false;
    }

    // ch:关闭设备 | en:Close device
    nRet = MV_CC_CloseDevice(m_camera_handle);
    if (MV_OK != nRet)
    {
//        printf("Close Device fail! nRet [0x%x]\n", nRet);
        return false;
    }

    // ch:销毁句柄 | en:Destroy handle
    nRet = MV_CC_DestroyHandle(m_camera_handle);
    if (MV_OK != nRet)
    {
//        printf("Destroy Handle fail! nRet [0x%x]\n", nRet);
        return false;
    }
    m_camera_handle = nullptr;
    return false;
}

bool HkCamera::softwareTrigger()
{
    if (m_camera_handle != nullptr)
    {
        

        int nRet = MV_CC_SetCommandValue(m_camera_handle, "TriggerSoftware");
        if (MV_OK != nRet)
        {
            return false;
        }
    }
    return true;
}

bool HkCamera::setExposureTime(double value)
{
    if (m_camera_handle != nullptr)
        if (MV_OK == MV_CC_SetFloatValue(m_camera_handle, "ExposureTime", (float)value))
            return true;
    return false;
}

bool HkCamera::setGainValue(double value)
 {
     if (m_camera_handle != nullptr)
         if (MV_OK == MV_CC_SetFloatValue(m_camera_handle, "Gain", (float)value))
             return true;
     return false;
 }

bool HkCamera::getExposureTime(double& value)
 {
     if (m_camera_handle == nullptr)
        return false;
     MVCC_FLOATVALUE stFloatValue = { 0 };

     int nRet = MV_CC_GetFloatValue(m_camera_handle, "ExposureTime", &stFloatValue);
     if (MV_OK != nRet)
     {
         return false;
     }
     value = stFloatValue.fCurValue;
     return true;
 }

bool HkCamera::getGainValue(double& value)
 {
     if (m_camera_handle == nullptr)
         return false;
     MVCC_FLOATVALUE stFloatValue = { 0 };

     int nRet = MV_CC_GetFloatValue(m_camera_handle, "Gain", &stFloatValue);
     if (MV_OK != nRet)
     {
         return false;
     }
     value = stFloatValue.fCurValue;
     return true;
 }

bool HkCamera::setTriggerMode(int index)
 {
     if (m_camera_handle == nullptr)
         return false;
     int nRet = MV_CC_SetEnumValue(m_camera_handle, "TriggerMode", index);
     if (MV_OK != nRet)
     {
         return false;
     }
     return true;
 }

bool HkCamera::setTriggerSource()
{
	if (m_camera_handle == nullptr)
        return false;
    int nRet = MV_CC_SetEnumValue(m_camera_handle, "TriggerSource", 7);
    if (MV_OK != nRet)
    {
         return false;
    }
    return true;
}

bool HkCamera::setFrameCount(unsigned int value)
 {
     if (m_camera_handle == nullptr)
         return false;

     int nRet = MV_CC_SetIntValue(m_camera_handle, "AcquisitionBurstFrameCount",value);
     if (MV_OK != nRet)
     {
         return false;
     }
     return true;
 }


bool HkCamera::startGrabbing()
{
    if (m_camera_handle == nullptr)
        return false;
    int nRet = MV_CC_StartGrabbing(m_camera_handle);
    if (MV_OK != nRet)
    {
        return false;
    };
    return true;
}

bool HkCamera::stopGrabbing()
{
    if (m_camera_handle == nullptr)
        return false;
    int nRet = MV_CC_StopGrabbing(m_camera_handle);
    if (MV_OK != nRet)
    {
        return false;
    }
    return true;
}


bool HkCamera::setOutput(bool value)
{
    if (m_camera_handle == nullptr)
        return false;
     int nRet = MV_CC_SetEnumValue(m_camera_handle, "LineSelector", 1);

     nRet = MV_CC_SetBoolValue(m_camera_handle, "LineInverter", value);
     if (MV_OK != nRet)
     {
         return false;
     }
     return true;
}
